package com.upbos.upm.login;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.upbos.cache.SingleCacheManager;
import com.upbos.core.ret.RetCode;
import com.upbos.core.ret.RetData;
import com.upbos.core.util.CookieUtils;
import com.upbos.core.util.RandomUtils;
import com.upbos.sso.SsoManager;
import com.upbos.sso.UserContext;
import com.upbos.sso.entity.SsoUser;
import com.upbos.sso.entity.Token;
import com.upbos.upm.common.Constants;
import com.upbos.upm.listener.UserLogoutListener;
import com.upbos.upm.cfg.CfgUtil;
import com.upbos.upm.common.CfgKeyConstants;
import com.upbos.upm.entity.Cfg;
import com.upbos.upm.entity.Module;
import com.upbos.upm.entity.User;
import com.upbos.upm.entity.UserCfg;
import com.upbos.upm.user.UserCfgUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import static com.upbos.core.ret.RetData.fail;
import static com.upbos.core.ret.RetData.success;

/**
 * <b>Application name：</b> LoginController.java <br>
 * <b>Application describing： 用户登录、登出以及获取用户菜单、权限等</b> <br>
 * <b>Copyright：</b> Copyright &copy; 2018 upbos.com 版权所有。<br>
 * <b>Company：</b> upbos.com <br>
 * <b>Date：</b> 2018年09月26日 23:28 <br>
 * <b>author：</b> <a href="mailto:wangjz@miyzh.com"> wangjz </a> <br>
 * <b>version：</b>V4.1.0 <br>
 */
@RestController
@RequestMapping("upm")
public class LoginController {

    private static Properties props = new Properties();
    /**
     * 用户session操作工具对象
     */
    @Resource
    private SsoManager ssoManager;
    @Resource

    private SingleCacheManager singleCacheManager;
    /**
     * 用户登录、登出以及获取用户菜单、权限服务
     */
    @Resource
    private LoginService loginService;


    @Resource
    private ApplicationContext applicationContext;

    /**
     * 获取应用系统的名称以及登录界面的背景图路径
     */
    @PostMapping("public/listCfg")
    public RetData<List<Cfg>> listCfg() {
        return success(CfgUtil.listCfg(CfgKeyConstants.APPLICATION_TITLE_KEY, CfgKeyConstants.APPLICATION_BK_IMG_KEY));
    }

    @PostMapping("public/getThemeColor")
    public RetData getThemeColor(UserContext userContext) {
        SsoUser user = userContext.getSsoUser();
        if (user == null) {
            return success(CfgUtil.getCfg(CfgKeyConstants.LAYOUT_THEME_COLOR_KEY));
        } else {
            return success(UserCfgUtils.getUserCfg(user.getUid(), CfgKeyConstants.LAYOUT_THEME_COLOR_KEY));
        }
    }

    /**
     * 验证登录名和密码是否合法
     *
     * @param request  request包装对象
     * @param response response包装对象
     * @param user     登录名和密码对象
     * @return 返回验证信息，
     */
    @PostMapping("public/login")
    public RetData login(HttpServletRequest request, HttpServletResponse response,
                         User user, String randomCode) throws Exception {
        String rCode = CookieUtils.getCookieValue(request, Constants.CACHE_RCODE);
        String cacheCode = singleCacheManager.getCache(Constants.CACHE_RCODE).get(rCode);
        if (randomCode == null || !randomCode.equals(cacheCode)) {
            return fail("验证码不正确");
        }
        return loginService.login(user, request, response, ssoManager);
    }

    @PostMapping("common/logout")
    public void logout(HttpServletRequest req, HttpServletResponse res) {
        // 登录成功，通知业务系统
        Token token = ssoManager.getToken(req);
        Map<String, UserLogoutListener> map = applicationContext.getBeansOfType(UserLogoutListener.class);
        UserContext context = new UserContext(ssoManager, req);
        map.forEach((s, userLoginListener) -> userLoginListener.notice(context));
        ssoManager.logout(req, res);
    }

    @PostMapping("common/main")
    public RetData main(HttpServletRequest req) {
        Token token = ssoManager.getToken(req);
        if (token == null) {
            return fail("您没有登录");
        }

        RetData retData = new RetData(RetCode.SUCCESS);

        // 用户拥有的功能菜单
        SsoUser ssoUser = ssoManager.getSsoUser(token.getId());
        List<Module> moduleTree = loginService.listUserModuleTree(ssoUser.getUid());
        retData.putData("moduleTree", moduleTree);

        User user = new User();
        user.setName(ssoUser.getName());
        retData.putData("user", user);

        String[] keys = {CfgKeyConstants.LAYOUT_KEY, CfgKeyConstants.LAYOUT_MENU_THEME_KEY, CfgKeyConstants.LAYOUT_TOP_WIDTH_KEY
                , CfgKeyConstants.LAYOUT_SIDER_LEFT_MENU_WIDTH_KEY
                , CfgKeyConstants.LAYOUT_SIDER_TOP_FIRST_LEVEL_MENU_KEY, CfgKeyConstants.APPLICATION_TITLE_KEY};
        // 用户自定义参数
        List<UserCfg> cfgs = UserCfgUtils.listUserCfg(ssoUser.getUid(), keys);
        retData.putData("cfgs", cfgs);

        return retData;
    }

    @RequestMapping("public/captcha")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String rCodeKey = CookieUtils.getCookieValue(request, Constants.CACHE_RCODE);
        if (rCodeKey == null) {
            rCodeKey = RandomUtils.getCharacterAndNumber(Constants.RCODE_COOKIE_ID_LENGTH);
            CookieUtils.setCookie(response, Constants.CACHE_RCODE, rCodeKey);
        }
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(85, 32, 4, 20);
        captcha.setBackground(Color.orange);
        // 存入缓存
        singleCacheManager.getCache(Constants.CACHE_RCODE).set(rCodeKey, captcha.getCode());
        captcha.write(response.getOutputStream());
    }
}